\section{\PrintfSeveralArgumentsSectionName}

Попробуем теперь немного расширить пример \IT{\HelloWorldSectionName}~(\myref{sec:helloworld}),
написав в теле функции \main:

\lstinputlisting[label=hw_c,style=customc]{patterns/03_printf/1.c}

% sections
\input{patterns/03_printf/x86/main}
\input{patterns/03_printf/ARM/main}
\input{patterns/03_printf/MIPS/main}

\subsection{\Conclusion{}}

Вот примерный скелет вызова функции:

\begin{lstlisting}[caption=x86,style=customasmx86]
...
PUSH третий аргумент
PUSH второй аргумент
PUSH первый аргумент
CALL функция
; модифицировать указатель стека (§если§ §нужно§)
\end{lstlisting}

\begin{lstlisting}[caption=x64 (MSVC),style=customasmx86]
MOV RCX, первый аргумент
MOV RDX, второй аргумент
MOV R8, третий аргумент
MOV R9, §4-й аргумент§
...
PUSH §5-й, 6-й аргумент, и~т.д. (если нужно)§
CALL функция
; §модифицировать указатель стека (если нужно)§
\end{lstlisting}

\begin{lstlisting}[caption=x64 (GCC),style=customasmx86]
MOV RDI, первый аргумент
MOV RSI, второй аргумент
MOV RDX, третий аргумент
MOV RCX, §4-й аргумент§
MOV R8, §5-й аргумент§
MOV R9, §6-й аргумент§
...
PUSH §7-й, 8-й аргумент, и~т.д. (если нужно)§
CALL функция
; §модифицировать указатель стека (если нужно)§
\end{lstlisting}

\begin{lstlisting}[caption=ARM,style=customasmARM]
MOV R0, первый аргумент
MOV R1, второй аргумент
MOV R2, третий аргумент
MOV R3, §4-й аргумент§
; §передать 5-й, 6-й аргумент, и~т.д., в стеке (если нужно)§
BL функция
; §модифицировать указатель стека (если нужно)§
\end{lstlisting}

\begin{lstlisting}[caption=ARM64,style=customasmARM]
MOV X0, первый аргумент
MOV X1, второй аргумент
MOV X2, третий аргумент
MOV X3, §4-й аргумент§
MOV X4, §5-й аргумент§
MOV X5, §6-й аргумент§
MOV X6, §7-й аргумент§
MOV X7, §8-й аргумент§
; §передать 9-й, 10-й аргумент, и~т.д., в стеке (если нужно)§
BL функция
; §модифицировать указатель стека (если нужно)§
\end{lstlisting}

\myindex{MIPS!O32}
\begin{lstlisting}[caption=MIPS (соглашение о вызовах O32),style=customasmMIPS]
LI $4, первый аргумент ; AKA $A0
LI $5, второй аргумент ; AKA $A1
LI $6, третий аргумент ; AKA $A2
LI $7, §4-й аргумент §; AKA $A3
; §передать 5-й, 6-й аргумент, и~т.д., в стеке (если нужно)§
LW temp_reg, адрес функции
JALR temp_reg
\end{lstlisting}

\subsection{Кстати}

\myindex{fastcall}
Кстати, разница между способом передачи параметров принятая в x86, x64, fastcall, ARM и MIPS неплохо иллюстрирует тот важный момент, что процессору, в общем, всё равно, как будут 
передаваться параметры функций. Можно создать гипотетический компилятор, который будет передавать их при 
помощи указателя на структуру с параметрами, не пользуясь стеком вообще.

\myindex{MIPS!O32}
Регистры \$A0\dots \$A3 в MIPS так названы только для удобства (это соглашение о вызовах O32).
Программисты могут использовать любые другие регистры (может быть, только кроме \$ZERO) для
передачи данных или любое другое соглашение о вызовах.

\ac{CPU} не знает о соглашениях о вызовах вообще.

Можно также вспомнить, что начинающие программисты на ассемблере передают параметры 
в другие функции обычно через регистры, без всякого явного порядка, или даже через глобальные переменные.
И всё это нормально работает.

